package com.cloudminds.resttest.ice;

import Ice.*;
import Ice.Object;
import IceGrid.QueryPrx;
import IceGrid.QueryPrxHelper;
import IceInternal.BasicStream;
import IceInternal.Incoming;
import com.cloudminds.resttest.ice.slice.aias.AiasSenderPrx;
import com.cloudminds.resttest.ice.slice.aias.AiasSenderPrxHelper;
import com.cloudminds.resttest.vo.CallParams;
import org.json.JSONObject;

import java.lang.Exception;
import java.util.ArrayList;
import java.util.Collections;
import java.util.UUID;

public class FrIceClient {

    private static final String TAG = "HS/AiasIceClient";
    private AiasIceClient aiasIceClient;
    private Communicator communicator = null;
    private AiasSenderPrx frSenderPrx = null;
    private Identity identity = null;
    private Connect_State state = Connect_State.disconnected;
    private String iceEndpoints = "";


    private enum Connect_State{
        connected,
        disconnected,
        connecting,
        disconnecting;
    }

    private static final int AIAS_CODE_SUCCESS = 1;

    public FrIceClient(){

    }
    //    private final MediaReceiver mediaReceiver = new MediaReceiver() {
//        @Override
//        public int callbackData(byte[] seq, Current current) {
//            return 0;
//        }
//
//        @Override
//        public int callbackControl(String control, Current current) {
//            return 0;
//        }
//    };
    private final Ice.Object object = new Object() {
        @Override
        public Object clone() throws CloneNotSupportedException {
            return null;
        }

        @Override
        public boolean ice_isA(String s) {
            return false;
        }

        @Override
        public boolean ice_isA(String s, Current current) {
            return false;
        }

        @Override
        public void ice_ping() {

        }

        @Override
        public void ice_ping(Current current) {

        }

        @Override
        public String[] ice_ids() {
            return new String[0];
        }

        @Override
        public String[] ice_ids(Current current) {
            return new String[0];
        }

        @Override
        public String ice_id() {
            return null;
        }

        @Override
        public String ice_id(Current current) {
            return null;
        }

        @Override
        public int ice_operationAttributes(String s) {
            return 0;
        }

        @Override
        public void ice_preMarshal() {

        }

        @Override
        public void ice_postUnmarshal() {

        }

        @Override
        public DispatchStatus ice_dispatch(Request request, DispatchInterceptorAsyncCallback dispatchInterceptorAsyncCallback) {
            return null;
        }

        @Override
        public DispatchStatus ice_dispatch(Request request) {
            return null;
        }

        @Override
        public DispatchStatus __dispatch(Incoming incoming, Current current) {
            return null;
        }

        @Override
        public void __write(BasicStream basicStream) {

        }

        @Override
        public void __read(BasicStream basicStream) {

        }

        @Override
        public void __write(OutputStream outputStream) {

        }

        @Override
        public void __read(InputStream inputStream) {

        }
    };
    public void connectAias(){

        if (state != Connect_State.disconnected){
            System.out.println("Connect ice abort, because ice state is not disconnected, current state is:"+state);
            return;
        }
        state = Connect_State.connecting;
        System.out.println("Connecting to aias");
        iceEndpoints = AiasIceParams.getEndpoints();
        if (iceEndpoints.isEmpty()){
            System.out.println("ice endpoints is null");
            return;
        }
        try {
            Properties properties = Util.createProperties();
            properties.setProperty("Ice.ImplicitContext","Shared");
            properties.setProperty("Ice.Warn.Connections","1");
            properties.setProperty("Ice.ACM.Heartbeat","3");
            properties.setProperty("Ice.ACM.Close","0");
            properties.setProperty("Ice.ACM.Timeout","0");
            properties.setProperty("Ice.ACM.Client.Timeout","0");
            properties.setProperty("Ice.Default.Timeout","10000");
            properties.setProperty("Ice.Default.InvocationTimeout","60000");
            properties.setProperty("Ice.Override.Timeout","10000");
            properties.setProperty("Ice.Override.ConnectTimeout","10000");
            properties.setProperty("Ice.Override.CloseTimeout","10000");
            properties.setProperty("Ice.Trace.Locator","2");
            properties.setProperty("IceGrid.Node.Trace.Adapter","2");
            properties.setProperty("IceGrid.Node.Trace.Server","3");
            properties.setProperty("Ice.Trace.Network","2");

            String iceLocator =  AiasIceParams.getGridLocator();
            if (!iceLocator.isEmpty()){
                properties.setProperty("Ice.Default.LocatorCacheTimeout","0");
                properties.setProperty("Ice.Default.Locator",AiasIceParams.getGridLocator());
            }

            InitializationData data = new InitializationData();
            data.properties = properties;
            communicator = Util.initialize(data);
            ObjectPrx proxy = communicator.stringToProxy(AiasIceParams.getEndpoints());


            QueryPrx queryPrx = QueryPrxHelper.checkedCast(proxy);
            if (queryPrx == null){
                System.out.println("Invalid queryPrx");
                state = Connect_State.disconnected;
                return;
            }
            ObjectPrx[] objectPrxes = queryPrx.findAllObjectsByType(AiasIceParams.ICE_FR_ADAPTER_TYPE);
            ArrayList<SObjPrx> prxList = new ArrayList<SObjPrx>();
            if (objectPrxes != null){
                for (ObjectPrx prx : objectPrxes){
                    SObjPrx op = new SObjPrx(prx);
                    prxList.add(op);
                }
            }

            if (prxList.size()>0){
                Collections.sort(prxList);
            }

            for (SObjPrx sop : prxList){
                if (!sop.getRobotType().isEmpty()){
                    if(!sop.getRobotType().startsWith("pepper")){
                        continue;
                    }
                }
                if (!sop.getTenantId().isEmpty()){
                    if (!sop.getTenantId().startsWith(CallParams.TENANT_ID)){
                        continue;
                    }
                }
                if (!sop.getServiceCode().isEmpty()){
                    if (!sop.getTenantId().startsWith(CallParams.SERVICE_CODE)){
                        continue;
                    }
                }
                frSenderPrx = AiasSenderPrxHelper.checkedCast(sop.getObjectPrx());
                break;
            }
            if (frSenderPrx == null) {
                System.out.println("Invalid Proxy!");
                return;
            }

            ObjectAdapter adapter = communicator.createObjectAdapter("");
            identity = new Identity();
            String uuid = UUID.randomUUID().toString();
            identity.name = uuid;
            adapter.add(object,identity);
            adapter.activate();
            proxy.ice_getCachedConnection().setAdapter(adapter);

            state = Connect_State.connected;
            System.out.println("Aias fr connected!");
            //handler.postDelayed(heartbeatRunnable, TIME_INTERVAL_AIAS_HB);

        }catch (LocalException e){
            System.out.println("connect aias error:"+e.getLocalizedMessage());
            state = Connect_State.disconnected;
            e.printStackTrace();
        }
    }

    public void forceConnect(){
        if (state != Connect_State.disconnected){
            String points = AiasIceParams.getEndpoints();
            if (points!=null && !points.isEmpty()){
                if (!points.equals(iceEndpoints)){
                    releaseConnect();
                }
            }
        }
        connectAias();
    }

    private void sendHeartbeat(){
        if (state != Connect_State.connected){
            System.out.println("sendHeartbeat ... ice is disconnected, so ignored!");
            return;
        }
        try {
            //Log.d(TAG,"send ice heartbeat");
            JSONObject msg = new JSONObject();
            msg.put("type","aias_ping");
//            aiasSenderPrx.aiasPing(msg.toString().getBytes(),identity);
//            handler.postDelayed(heartbeatRunnable,TIME_INTERVAL_AIAS_HB);

        }catch (Exception e){

        }
    }

    private Runnable heartbeatRunnable = new Runnable() {
        @Override
        public void run() {
            sendHeartbeat();
        }
    };

    public void sendFace(final String object){
        System.out.print("开始发送人脸");
        if (state != Connect_State.connected){
            System.out.println("send face data, but ice is not connected!");
            return;
        }
        try {
            int result = frSenderPrx.mediaWebCamStream(object.getBytes(),identity);
            if (result == AIAS_CODE_SUCCESS){
                System.out.println("send face successful!");
            } else {
                System.out.println("send face failed! result:"+result);
            }

        }catch (LocalException e){

        }

    }

    private void releaseConnect(){
        if (frSenderPrx!=null && frSenderPrx.ice_getCachedConnection()!=null){
            ObjectAdapter adapter = frSenderPrx.ice_getCachedConnection().getAdapter();
            if (adapter != null){
                adapter.destroy();
            }
        }
        state = Connect_State.disconnected;
    }
}
